package demo1;

import org.junit.Test;

import java.nio.ByteBuffer;

/**
 * 一：
 * 缓冲区：在JavaNIO当中负责数据的存取，底层是数组，用于存放不同类型的数据
 * 八大基本类型除了Boolean之外每个类型都有缓冲区
 * 但是他们的管理方式几乎一致，都是使用allocate()分配缓冲区空间
 * <p>
 * 二：缓冲区有两个核心方法
 * 1；get：获取缓冲区的数据
 * 2：put：存入到数据缓冲区
 * <p>
 * 三：缓冲区的四个核心属性
 * 1：capacity：容量--》表示缓冲区中最大存储数据的容量，一旦声明，不可改变
 * 2：limit   ：界限--》表示缓冲区中可以操作数据的大小，limit后边的数据不能进行读写
 * 3：position：位置--》表示缓冲区中正在操作数据的位置
 * 4：mark    ：标记--》记录当前position的位置，可以通过reset（）恢复到mark的位置
 *
 * 0 <= mark <= position  <= limit  <= capacity
 *
 * 四： 直接缓冲区与非直接缓冲区
 *      *非直接缓冲区 ：通过allocate方法分配的缓冲区，将缓冲建立在jvm的内存中
 *      *直接缓冲区   ：通过allocateDirect方法分配直接缓冲区，将缓冲区建立在操作系统的物理内存中  **某种情况下可以提高效率
 */
public class TestBuffer {

    @Test
    public void test2() {
        ByteBuffer allocate = ByteBuffer.allocate(1024);
        allocate.put(new String("abcd").getBytes());
        allocate.flip();
        byte[] dst = new byte[allocate.limit()];
        allocate.get(dst, 0, 2);
        System.out.println(new String(dst, 0, dst.length));

        if (allocate.hasRemaining()){
            System.out.println("查看还有多少的剩余数据   ---> "+allocate.remaining());
        }

        allocate.mark();
        System.out.println("****************** allocate *************************************");
        System.out.println("当前操作的数据位置：" + allocate.position());
        System.out.println("现在可以操作的数据大小：" + allocate.limit());
        System.out.println("最大的操作数据：" + allocate.capacity());

        allocate.get(dst, 2, 2);
        System.out.println("****************** get *************************************");
        System.out.println(new String(dst, 2, 2));
        System.out.println("当前操作的数据位置：" + allocate.position());
        System.out.println("现在可以操作的数据大小：" + allocate.limit());
        System.out.println("最大的操作数据：" + allocate.capacity());

        allocate.reset();
        System.out.println("****************** reset *************************************");
        System.out.println("当前操作的数据位置：" + allocate.position());
        System.out.println("现在可以操作的数据大小：" + allocate.limit());
        System.out.println("最大的操作数据：" + allocate.capacity());


    }

    @Test
    public void test1() {

        //1.分配一个指定大小的缓冲区
        ByteBuffer allocate = ByteBuffer.allocate(1024);
        System.out.println("****************** allocate *************************************");
        System.out.println("当前操作的数据位置：" + allocate.position());
        System.out.println("现在可以操作的数据大小：" + allocate.limit());
        System.out.println("最大的操作数据：" + allocate.capacity());


        /*
        存入数据
         */
        allocate.put(new String("abcd").getBytes());
        System.out.println("*********************** put ********************************");
        System.out.println("当前操作的数据位置：" + allocate.position());
        System.out.println("现在可以操作的数据大小：" + allocate.limit());
        System.out.println("最大的操作数据：" + allocate.capacity());

        /*
        切换模式
         */
        allocate.flip();
        System.out.println("******************* flip ************************************");
        System.out.println("当前操作的数据位置：" + allocate.position());
        System.out.println("现在可以操作的数据大小：" + allocate.limit());
        System.out.println("最大的操作数据：" + allocate.capacity());

        /*
        读取缓冲区的数据
         */
        System.out.println("***************** get **************************************");
        byte[] dst = new byte[allocate.limit()];
        allocate.get(dst);
        System.out.println(new String(dst, 0, dst.length));

        System.out.println("****************** get *************************************");
        System.out.println("当前操作的数据位置：" + allocate.position());
        System.out.println("现在可以操作的数据大小：" + allocate.limit());
        System.out.println("最大的操作数据：" + allocate.capacity());


        /*
        rewind 可重复读
         */

        allocate.rewind();
        System.out.println("****************** rewind *************************************");
        System.out.println("当前操作的数据位置：" + allocate.position());
        System.out.println("现在可以操作的数据大小：" + allocate.limit());
        System.out.println("最大的操作数据：" + allocate.capacity());

        /*
        clear  清空缓冲区  但是缓冲区的数据依然存在，不过他们处于被遗忘的状态
        意思就是   position  limit  capacity 回到最初的状态，数据还在那里
         */

        allocate.clear();
        System.out.println("****************** clear *************************************");
        System.out.println("当前操作的数据位置：" + allocate.position());
        System.out.println("现在可以操作的数据大小：" + allocate.limit());
        System.out.println("最大的操作数据：" + allocate.capacity());

        System.out.println((char) allocate.get(0));

    }
}
